package edu.siu.math.egut.util;

import java.io.IOException;
import java.io.Serializable;

import edu.siu.math.egut.io.Constants;
import edu.siu.math.egut.io.LiE;
import edu.siu.math.egut.io.OutputPref;
import edu.siu.math.egut.main.OutputStyle;

/**
 * @author josephhundley
 *
 */
public class WeylWord implements Serializable{
    public Group getG() {
        return g;
    }

    public void setG(Group g) {
        this.g = g;
    }

    public int[] getWord() {
        return word;
    }

    public void setWord(int[] word) {
        this.word = word;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    /**
     * 
     */
    private static final long serialVersionUID = 1003078377161384937L;
    private Group g;
    private int[] word;
    
    public WeylWord(int[] w, Group g1){
	g = g1;
	word = 
	    checkDigits(w,g.getRank());
	
    }
    
    private int[] checkDigits(int[] w, int rank) {
	for( int i =0; i < w.length; i++){
	    if(w[i] <1 || w[i] > rank){
		System.out.println("Attempt to initialize Weyl element with bad data.");
		System.exit(1);
	    }
	    
	}
	    
	return w;
    }

    WeylWord( String s, Group g1 ){
	g=g1;
	word = readAndCheckDigits(s, g.getRank());
    }

    private int[] readAndCheckDigits(String s, int rank) {
	int[] result = new int[s.length()];
	for( int i =0; i < s.length(); i++){
	    int d = edu.siu.math.egut.io.Algorithms.value(s.charAt(i));
	    if(d <1 || d > rank){
		System.out.println("Attempt to initialize Weyl element with bad data.");
		System.exit(1);
	    }
	    result[i] = d;
	    
	}
	    
	return result;
    }

    public static WeylWord read(String string, Group g) throws WeylWordReadException {
	if(!Algorithms.representsWeylWord(string, g.getRank()))
	    throw new WeylWordReadException();
	
	return new WeylWord( 
		edu.siu.math.egut.io.Algorithms.tupleFromString(string), 
		g);
    }

    public String toString(OutputStyle sty) {
	
	
	switch(sty)
	{
	case TEX:
	    String raw = "w["+edu.siu.math.egut.io.Algorithms.tupleToShortString(word)+"]";
	    if( raw.length() < Constants.SCREEN_WIDTH)
		return raw;
	    else{ 
		StringBuilder sb = new StringBuilder("\\begin{array}{r}w[");
		int width = 2;
		for( int i = 0; i < word.length; i++){
		    if(width >= Constants.SCREEN_WIDTH){
			sb.append("\\\\\n");
			width=3;
			
		    }
		    sb.append(Integer.toString(word[i]));
		}
		sb.append("]\\end{array}");
		return sb.toString();
	    }
	case LIE:
	    return edu.siu.math.egut.io.Algorithms.tupleToString(word);
	case SCREEN:
	    return edu.siu.math.egut.io.Algorithms.tupleToShortString(word);
	    
	}
	return edu.siu.math.egut.io.Algorithms.tupleToString(word);
	
	
    }

    public static WeylWord parse(String input, Group g) {
		if(!Algorithms.representsWeylWord(input, g.getRank()))
		    return null;
		
		return new WeylWord( 
			edu.siu.math.egut.io.Algorithms.tupleFromString(input), 
			g);	    
		}

    public static WeylWord reduceByInverse(WeylWord w, WeylWord w1, Group g1) throws WeylWordReadException, IOException {
	LiE lie = new LiE();
	return WeylWord.read(
		edu.siu.math.egut.io.Algorithms.removeWhiteSpaceCommasAndBrackets(
		lie.exec("reduce(" +
		w.toString(OutputStyle.LIE)+"^inverse("+
		w1.toString(OutputStyle.LIE)+"),"+g1.toString()+")",
		OutputPref.SHOW)), g1);
    }
    }

     
    

